#include <QtGui>
#include <iostream>

#include "operationDialog.h"
#include "src/color.h"

OperationDialog::OperationDialog(CombinedObject *_combinedObject, ObjectTreeItem *_item, QTreeWidgetItem *_root, Scene *_scene, QWidget *_parent)
    : QDialog(_parent), combinedObject(_combinedObject), item(_item), root(_root), scene(_scene){

    setWindowTitle(QString::fromUtf8("Modificar objeto ").append(QString::number(_combinedObject->getId())));

    Color color = combinedObject->getColor();
    colorR = color.red * 255;
    colorG = color.green * 255;
    colorB = color.blue * 255;
    colorAlpha = color.alpha * 255;

    operation = combinedObject->getType();
    remove = false;

    rotationX = 0;
    rotationY = 0;
    rotationZ = 0;
    onlyRotated = true;
    rotated = false;
    onlyChangedColor = true;

    createLayout();
}

OperationDialog::~OperationDialog(){
    delete colorPushButton;
    delete operationBox;
}

void OperationDialog::createLayout(){
    QLabel *changeOperationLabel = new QLabel(QString::fromUtf8("Mudar operação:"));

    QComboBox *operationComboBox = new QComboBox();
    operationComboBox->addItem(QString::fromUtf8("União"));
    operationComboBox->addItem(QString::fromUtf8("Interseção"));
    operationComboBox->addItem(QString::fromUtf8("Diferença"));
    operationComboBox->setCurrentIndex(operation);
    connect(operationComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeOperation(int)));



    QLabel *rotateXLabel = new QLabel(QString::fromUtf8("X:"));

    QComboBox *rotateXComboBox = new QComboBox();
    rotateXComboBox->addItem(QString::fromUtf8("0°"));
    rotateXComboBox->addItem(QString::fromUtf8("90°"));
    rotateXComboBox->addItem(QString::fromUtf8("180°"));
    rotateXComboBox->addItem(QString::fromUtf8("270°"));
    rotateXComboBox->setCurrentIndex(rotationX);
    connect(rotateXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeRotationX(int)));

    QLabel *rotateYLabel = new QLabel(QString::fromUtf8("Y:"));

    QComboBox *rotateYComboBox = new QComboBox();
    rotateYComboBox->addItem(QString::fromUtf8("0°"));
    rotateYComboBox->addItem(QString::fromUtf8("90°"));
    rotateYComboBox->addItem(QString::fromUtf8("180°"));
    rotateYComboBox->addItem(QString::fromUtf8("270°"));
    rotateYComboBox->setCurrentIndex(rotationY);
    connect(rotateYComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeRotationY(int)));

    QLabel *rotateZLabel = new QLabel(QString::fromUtf8("Z:"));

    QComboBox *rotateZComboBox = new QComboBox();
    rotateZComboBox->addItem(QString::fromUtf8("0°"));
    rotateZComboBox->addItem(QString::fromUtf8("90°"));
    rotateZComboBox->addItem(QString::fromUtf8("180°"));
    rotateZComboBox->addItem(QString::fromUtf8("270°"));
    rotateZComboBox->setCurrentIndex(rotationZ);
    connect(rotateZComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeRotationZ(int)));

    QHBoxLayout *rotationLayout = new QHBoxLayout;
    rotationLayout->addWidget(rotateXLabel);
    rotationLayout->addWidget(rotateXComboBox);
    rotationLayout->addStretch(1);
    rotationLayout->addWidget(rotateYLabel);
    rotationLayout->addWidget(rotateYComboBox);
    rotationLayout->addStretch(1);
    rotationLayout->addWidget(rotateZLabel);
    rotationLayout->addWidget(rotateZComboBox);
    rotationLayout->addStretch(1);

    QGroupBox *rotationGroupBox = new QGroupBox(QString::fromUtf8("Rotação"));
    rotationGroupBox->setLayout(rotationLayout);

    colorPushButton = new QPushButton(tr("Cor"));
    connect(colorPushButton, SIGNAL(clicked()), this, SLOT(changeColor()));
    setButtonColor();

    QHBoxLayout *operationLayout = new QHBoxLayout;
    operationLayout->addWidget(changeOperationLabel);
    operationLayout->addWidget(operationComboBox);
    operationLayout->addStretch(1);

    QVBoxLayout *objectLayout = new QVBoxLayout;
    objectLayout->addLayout(operationLayout);
    objectLayout->addWidget(colorPushButton);
    objectLayout->addStretch(1);

    operationBox = new QGroupBox(QString::fromUtf8("Objeto"));
    operationBox->setLayout(objectLayout);


    QCheckBox *removeOperationCheckBox = new QCheckBox(QString::fromUtf8("Cancelar operação"));
    connect(removeOperationCheckBox, SIGNAL(clicked(bool)), this, SLOT(removeOperation(bool)));



    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    connect(buttonBox, SIGNAL(accepted()), this, SLOT(change()));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
    buttonBox->setLocale(QLocale(QLocale::Portuguese, QLocale::Brazil));

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(rotationGroupBox);
    mainLayout->addWidget(operationBox);
    mainLayout->addWidget(removeOperationCheckBox);
    mainLayout->addWidget(buttonBox);
    mainLayout->addStretch(1);

    setLayout(mainLayout);
}

void OperationDialog::setButtonColor(){
    //    QString colorStr = QString::fromUtf8("color: rgb(255, 255, 255);\n" "background-color: rgb(85, 0, 0, 255);");
    QString colorStr;
    if(colorR + colorB + colorG + colorAlpha < 600){
        colorStr = QString::fromUtf8("color: rgb(255, 255, 255);\n");
    }else{
        colorStr = QString::fromUtf8("color: rgb(0, 0, 0);\n");
    }
    colorStr.append(QString::fromUtf8("background-color: rgb("));
    colorStr.append(QString::number(colorR));
    colorStr.append(QString::fromUtf8(", "));
    colorStr.append(QString::number(colorG));
    colorStr.append(QString::fromUtf8(", "));
    colorStr.append(QString::number(colorB));
    colorStr.append(QString::fromUtf8(", "));
    colorStr.append(QString::number(colorAlpha));
    colorStr.append(QString::fromUtf8(");"));

    colorPushButton->setStyleSheet(colorStr);
}

void OperationDialog::change(){
    std::vector<Object *> objects;
    if(remove){
        QTreeWidgetItem *parent = item->parent();
        if(parent == NULL){
            parent = root;
            scene->deleteObject(combinedObject);
        }else{
            ((CombinedObject *)((ObjectTreeItem *)parent)->getObject())->deleteObject(combinedObject);
        }

        for(int i = item->childCount(); i > 0; i--){
            QTreeWidgetItem *currentItem = item->child( i-1 );
            Object *currentObject = ((ObjectTreeItem *)currentItem)->getObject();
            if(parent == root){//so refaz a octree desses objetos se seles forem soltos
                scene->addObject(currentObject);
                objects.push_back(currentObject);
            }else{//so forem combinado com outros, refaz a octree do primero pai
                ((CombinedObject *)((ObjectTreeItem *)parent)->getObject())->addObject(currentObject);
            }
            combinedObject->deleteObject(currentObject);

            item->removeChild(currentItem);
            parent->addChild(currentItem);
        }


        parent->removeChild(item);
        delete item;
        delete combinedObject;

        if(parent != root){
            objects.clear();
            while(parent->parent() != NULL){
                parent = parent->parent();
            }
            objects.push_back(((ObjectTreeItem *)parent)->getObject());
        }


    }else{
        combinedObject->changeOperation(operation);
        combinedObject->setColor(Color(colorR / 255.0, colorG / 255.0, colorB / 255.0, colorAlpha / 255.0));
        combinedObject->rotate(rotationX, rotationY, rotationZ);
        item->update();
        objects.push_back(combinedObject);

        if(rotated && onlyRotated){
            emit rotateOctree(combinedObject, rotationX, rotationY, rotationZ);
            accept();
            return;
        }

        if(onlyChangedColor){
            accept();
            return;
        }

    }
    emit redoOctree(objects);



    accept();
}

void OperationDialog::changeColor(){
    QColor color = QColorDialog::getColor(QColor(colorR, colorG, colorB, colorAlpha), this, "Escolha a cor", QColorDialog::ShowAlphaChannel);
    if (color.isValid()){
        colorR = color.red();
        colorG = color.green();
        colorB = color.blue();
        colorAlpha = color.alpha();
    }
    setButtonColor();
}

void OperationDialog::changeOperation(int _index){
    onlyRotated = false;
    onlyChangedColor = false;
    operation = _index;
}

void OperationDialog::removeOperation(bool _b){
    operationBox->setDisabled(_b);
    remove = _b;
}

void OperationDialog::changeRotationX(int _x){
    rotated = true;
    onlyChangedColor = false;
    rotationX = _x;
}

void OperationDialog::changeRotationY(int _y){
    rotated = true;
    onlyChangedColor = false;
    rotationY = _y;
}

void OperationDialog::changeRotationZ(int _z){
    rotated = true;
    onlyChangedColor = false;
    rotationZ = _z;
}
